package com.mmm.user.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.mmm.user.service.JwtService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * @email 1067559930@qq.com
 * @author: One
 * @date: 2022/03/01
 * @time: 16:26
 */
@Service
public class JwtServiceImpl implements JwtService {

    @Value("${rush.security.jwt-key}")
    private String jwtKey;
    @Value("${rush.security.expire-time}")
    private Integer expireTime;

    @Override
    public String makeToken(Long uid, Integer scope,Integer universityId) {
        Map<String, Date> tokenTime = this.getTokenTime();
        Algorithm algorithm = Algorithm.HMAC256(jwtKey);
        String sign = JWT.create()
                .withClaim("uid", uid)
                .withClaim("universityId", universityId)
                .withClaim("scope", scope)
                .withClaim("now", tokenTime.get("now"))
                .withClaim("expireTime", tokenTime.get("expireTime"))
                .sign(algorithm);

        return sign;
    }

    @Override
    public Boolean verify(String token) {
        DecodedJWT verify;
        try {
            String authorization = token.split(" ")[1];
            Algorithm algorithm = Algorithm.HMAC256(jwtKey);
            JWTVerifier jwt = JWT.require(algorithm).build();
             verify = jwt.verify(authorization);
        } catch (JWTVerificationException e) {
            return false;
        }
        return true;
    }

    @Override
    public Map<String, String> getClaimMap(String authorization) {
//        String authorization = (String)request.getHeader("Authorization");
        if (authorization == null) {
            throw new RuntimeException("请先登录");
        }
        if (!authorization.startsWith("Bearer")) {
            throw new RuntimeException("token错误");
        }
        String bearer = authorization.split(" ")[1];
        Map<String, Claim>  claim = this.getClaim(bearer);
//        切记要和传入的 值类型 一样 否则会获取不不到值
        Long uid = claim.get("uid").asLong();
        Integer universityId = claim.get("universityId").asInt();

        Integer scope = claim.get("scope").asInt();
        Date now = claim.get("now").asDate();
        Date expireTime = claim.get("expireTime").asDate();
        Map<String,String> map=new HashMap<>();
        map.put("uid",uid.toString());
        map.put("universityId",universityId.toString());
        map.put("scope",scope.toString());
        map.put("now",now.toString());
        map.put("expireTime",expireTime.toString());
        return map;
    }

    private  Map<String, Claim> getClaim(String authorization) {
        Algorithm algorithm = Algorithm.HMAC256(jwtKey);
        JWTVerifier jwt = JWT.require(algorithm).build();
        DecodedJWT verify = jwt.verify(authorization);
        return verify.getClaims();
    }

    private  Map<String, Date> getTokenTime() {
        Calendar calendar = Calendar.getInstance();
        Date now = calendar.getTime();
        calendar.set(Calendar.SECOND, expireTime);
        HashMap<String, Date> map = new HashMap<>();
        map.put("now", now);
        map.put("expireTime", calendar.getTime());
        return map;
    }
}
